/**
 * 封装：全局公用的axios方法=》ajax请求的方法
 */
import axios from 'axios'
// 处理精度失真
import JSONBIGINT from 'json-bigint'
// 导入store(存储token)
import store from '../store'
// 导入路由
import router from '../router'

// 创建一个自己的axios实例
const MyAxios = axios.create({
  baseURL: 'http://ttapi.research.itcast.cn/app/v1_0/',
  transformResponse: [
    function (data) {
      try {
        return JSONBIGINT.parse(data)
      } catch (error) {
        return data
      }
    }
  ]
})

// 添加请求和响应的拦截器
// Add a request interceptor
MyAxios.interceptors.request.use(function (config) {
  // Do something before request is sent
  // console.log('请求开始了', config.url)
  // 统一添加header中的token
  const { user } = store.state
  if (user.token && config.url !== 'authorizations') {
    config.headers.Authorization = `Bearer ${user.token}`
  }
  // 处理接口版本问题
  if (config.url === 'articles') {
    config.baseURL = config.baseURL.replace('v1_0', 'v1_1')
  }
  return config
}, function (error) {
  // Do something with request error
  return Promise.reject(error)
})

// Add a response interceptor
MyAxios.interceptors.response.use(function (response) {
  // Any status code that lie within the range of 2xx cause this function to trigger
  // Do something with response data
  // console.log('数据返回了', response)
  // 统一处理返回数据（简化）

  return {
    status: response.status,
    data: response.data.data
  }
}, async function (error) {
  // Any status codes that falls outside the range of 2xx cause this function to trigger
  // Do something with response error
  console.log(error.response)
  // 处理401token失效的情况
  /**
   * 1. 没有登录=> 重新登录
   * 2. 登录过=》token失效/refresh_token没失效 =》刷新token
   * 3. 登录过=》token失效/refresh_token失效=》重新登录
   */
  // token数据=》判断是否登录过
  const { user } = store.state
  // 跳登录的配置
  const loginConfig = { path: '/login', query: { redirectUrl: router.currentRoute.path } }
  try {
    if (error.response && error.response.status === 401) {
      // 1. 没有登录=> 重新登录
      if (!user.token || !user.refresh_token) {
        router.push(loginConfig)
        return Promise.reject(error)
      }
      // 2. 登录过=》token失效/refresh_token没失效 =》刷新token(调用接口)
      const { status, data } = await MyAxios.put('authorizations', null, {
        headers: {
          Authorization: `Bearer ${user.refresh_token}`
        }
      })
      // 获取到新的token了
      if (status === 201) {
        console.log(data)
        // 更新本地token
        store.commit('setToken', {
          token: data.token,
          refresh_token: user.refresh_token
        })
        // 重新调用上次401失败的请求
        console.log('请求配置：', error.config)
        return MyAxios(error.config)
      }
    }
  } catch (error) {
    console.log('3. 登录过=》token失效/refresh_token失效=》重新登录', error)
    router.push(loginConfig)
    return Promise.reject(error)
  }

  return Promise.reject(error)
})

// vue插件方法
const MyAxiosPlugin = function (Vue) {
  Vue.prototype.request = MyAxios
}

export { MyAxiosPlugin }

export default MyAxios
